#include "usart.h"

/*******************************************************************************************************************************************/
/*                                                          USART1                                                                         */
/*******************************************************************************************************************************************/

void USART2_Init(unsigned int BaudRate)
{
	GPIO_InitTypeDef GPIO_InitStruct;
	USART_InitTypeDef	USART_InitStructure;

//	NVIC_InitTypeDef NVIC_InitStructure;

	//RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2 | RCC_APB2Periph_GPIOA, ENABLE);			//使能USART1，GPIOA时钟   
	
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_AFIO,ENABLE); 
    RCC_APB1PeriphClockCmd( RCC_APB1Periph_USART2,ENABLE);
	
	/*初始化USART1的Tx、Rx引脚*/
	//PA9 复用推挽输出
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_2;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA,&GPIO_InitStruct);
	
	//PA10浮空输入
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin_3;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init(GPIOA,&GPIO_InitStruct);

//	PA9outAF_PP();   //PA9 复用推挽输出
//	PA10inFLOATING();//PA10浮空输入
	
	
	USART_InitStructure.USART_BaudRate = BaudRate;							                      //波特率
	USART_InitStructure.USART_WordLength = USART_WordLength_8b;				              	//字长8位
	USART_InitStructure.USART_StopBits = USART_StopBits_1;						                //停止位1位
	USART_InitStructure.USART_Parity = USART_Parity_No;						                    //无奇偶校验
	USART_InitStructure.USART_HardwareFlowControl	= USART_HardwareFlowControl_None;		//无硬件数据流控制
	USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx;				          	//收/发模式	
	USART_Init(USART2, &USART_InitStructure);
	//USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);							     //开启接收中断
	
	
	//中断设置
//	NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);				    //中断分组1：1位抢占优先级，3位响应优先级
//	NVIC_InitStructure.NVIC_IRQChannel = USART2_IRQn;			    //中断通道
//	NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 1; //抢占优先级
//	NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3;		 	  //子优先级
//	NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE;				    //使能中断
//	NVIC_Init(&NVIC_InitStructure);
	USART_Cmd(USART2, ENABLE);

#if 0
	GPIO_InitTypeDef GPIO_Init_Structure;
	USART_InitTypeDef USART_Init_Structure;
	NVIC_InitTypeDef NVIC_Init_Structure;	
	
	/*开启串口2时钟和GPIO时钟*/
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE);
	RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2 , ENABLE);
	/*配置GPIO口工作模式*/
	GPIO_Init_Structure.GPIO_Mode = GPIO_Mode_AF_PP;
	GPIO_Init_Structure.GPIO_Pin = GPIO_Pin_2;
	GPIO_Init_Structure.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOA , &GPIO_Init_Structure);//PA2,USART2_TX,复用推挽输出
	
	GPIO_Init_Structure.GPIO_Mode = GPIO_Mode_IN_FLOATING;
	GPIO_Init_Structure.GPIO_Pin = GPIO_Pin_3;
	GPIO_Init_Structure.GPIO_Speed = GPIO_Speed_10MHz;//输入无效
	GPIO_Init(GPIOA , &GPIO_Init_Structure);//PA3,USART2_RX浮空输入
	/*串口参数初始化*/
	USART_Init_Structure.USART_BaudRate = BaudRate;
	USART_Init_Structure.USART_HardwareFlowControl = USART_HardwareFlowControl_None;
	USART_Init_Structure.USART_Mode = USART_Mode_Rx |USART_Mode_Tx;
	USART_Init_Structure.USART_Parity = USART_Parity_No;
	USART_Init_Structure.USART_StopBits = USART_StopBits_1;
	USART_Init_Structure.USART_WordLength = USART_WordLength_8b;
	USART_Init(USART2 , &USART_Init_Structure);
	/*开启串口中断*/
	USART_ITConfig(USART2 , USART_IT_RXNE , ENABLE);
	/*配置串口2的中断优先级*/
	NVIC_Init_Structure.NVIC_IRQChannel = USART2_IRQn;//串口2中断通道
	NVIC_Init_Structure.NVIC_IRQChannelCmd = ENABLE;
	NVIC_Init_Structure.NVIC_IRQChannelPreemptionPriority = 3;
	NVIC_Init_Structure.NVIC_IRQChannelSubPriority = 3;
	NVIC_Init(&NVIC_Init_Structure);
	/*使能串口*/
	USART_Cmd(USART2 , ENABLE);
#endif
}

/*****************************************************
如果开启了接收
*****************************************************/
#if EN_USART1_RX //如果开启了USART1接收
u8 USART1_RX_BUF[USART1_REC_LEN] __attribute__ ((at(0x20001000)));  //接收缓冲，最大USART1_REC_LEN个字节。 设定起始地址为0x20001000  
u16 USART1_RX_STA = 0;      //接收状态标记
u16 USART1_RX_CNT = 0;      //接收的字节数

void USART2_IRQHandler(void)                	
{
	u8 res;
	
	if(USART2->SR & (1<<5))
	{
		res = USART2->DR;
		
		if(USART1_RX_CNT<USART1_REC_LEN)
		{
			USART1_RX_BUF[USART1_RX_CNT] = res;
			USART1_RX_CNT++;
		}
	}
} 
#endif








/*******************************************************************************************************************************************/
/*                                     以下代码实现printf输出（无需MircoLIB）                                                              */
/*******************************************************************************************************************************************/

/*****************************************************
*function:	写字符文件函数
*param1:	输出的字符
*param2:	文件指针
*return:	输出字符的ASCII码
******************************************************/
//int fputc(int ch, FILE *f)
//{
//	while((USART2->SR & 0x40) == 0);
//	USART2->DR = (u8) ch;
//	return ch;
//}

//int fputc(int ch, FILE *f)
//{
//	//while(USART_GetFlagStatus(USART2,USART_FLAG_TC) != SET);   
//    USART_SendData(USART2,(unsigned char)ch);      
//    while(USART_GetFlagStatus(USART2,USART_FLAG_TC) != SET);    
//    return (ch);
//}

int fputc(int ch, FILE *f) 
{
		/* ??????????? */
		USART_SendData(USART2, (uint8_t) ch);
		
		/* ?????? */
		while (USART_GetFlagStatus(USART2, USART_FLAG_TC) == RESET);		
	
		return (ch);
}
/********** 禁用半主机模式 **********/
//#pragma import(__use_no_semihosting)
// 
//struct __FILE
//{
//	int handle;
//};
// 
//FILE __stdout;
// 
//void _sys_exit(int x)
//{
//	x=x;
//}




/*******************************************************************************************************************************************/
/*                                                                     itoa                                                                */
/*******************************************************************************************************************************************/
//static char *itoa(int value,char *string,int radix)
//{
//	int i,d;
//	int flag = 0;
//	char *ptr = string;
//	
//	if(radix != 10)
//	{
//		*ptr = 0;
//		return string;
//	}
//	
//	if(!value)
//	{
//		*ptr++ = 0x30;
//		*ptr = 0;
//		return string;
//	}
//	
//	if(value < 0)
//	{
//		*ptr++ = '-';
//		value *= -1;
//	}
//	
//	for(i=10000;i>0;i /= 10)
//	{
//		d = value / i;
//		
//		if(d || flag)
//		{
//			*ptr++ = (char)(d + 0x30);
//			value -= (d * i);
//			flag = 1;
//		}
//	}
//	
//	*ptr = 0;
//	return string;
//}


/*******************************************************************************************************************************************/
/*                                                  用户自定义的USART1输出函数 printf1                                                     */
/*******************************************************************************************************************************************/
//void printf1(u8 *data,...)
//{
//	const char *s;
//	int d;
//	char buf[16];
//	va_list ap;
//	va_start(ap,data);
//	while( *data != 0)
//	{
//		if( *data == 0x5C ) // '\'
//		{
//			switch ( *++data )
//			{
//				case 'r':
//					USART_SendData(USART1,0x0D);
//					data++;
//					break;
//				
//				case 'n':
//					USART_SendData(USART1,0x0A);
//					data++;
//					break;
//				
//				default:
//					data++;
//					break;
//			}
//		}
//		else if( *data == '%' )
//		{
//			switch ( *++data )
//			{
//				case 's': //字符串
//					s = va_arg(ap,const char *);
//					for(;*s;s++)
//					{
//					USART_SendData(USART1,*s);
//					while( USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET );
//					}
//					data++;
//					break;
//					
//				case 'd':
//					d = va_arg(ap,int);
//					itoa(d,buf,10);
//				
//					for(s = buf;*s;s++)
//					{
//						USART_SendData(USART1,*s);
//						while( USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET );
//					}
//					data++;
//					break;
//				
//				default:
//					data++;
//					break;
//			}
//		}
//		else USART_SendData(USART1,*data++);
//		while( USART_GetFlagStatus(USART1,USART_FLAG_TXE) == RESET);
//	}
//}





